/**
 * 
 */
package com.xuyue;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xuyue.entity.StopLine;
import com.xuyue.util.HttpUtil;
import com.xuyue.util._12306Util;


/**
 * @author tony
 *
 */
public class GoToBeijing {
	
	//车站编码与名称对应关系
	@SuppressWarnings("serial")
	private static final HashMap<String, String> STATIONMAPPING =new HashMap<String, String>(){{  
	      put("WHN","武汉");  
	      put("BXP","北京西");       
	      put("HKN","汉口");       
	}};
	
	/**
	 * 设置Get请求头
	 * @param get
	 */
	private static void setGetRequestHeaders(HttpGet get) {
		get.addHeader("Accept",_12306Util.accept);
		get.addHeader("Accept-Encoding", _12306Util.acceptEncoding);
		get.addHeader("Accept-Language", _12306Util.acceptLanguage);
		get.addHeader("User-Agent",_12306Util.userAgent);
	}
	
	/**
	 * 初始化12306登陆
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	private static void initLogin() throws ClientProtocolException, IOException {
		HttpGet getMethod = new HttpGet(_12306Util.initUrl);
		setGetRequestHeaders(getMethod);
		CloseableHttpResponse response = _12306Util.getHttpClient().execute(getMethod);
		int statusCode = response.getStatusLine().getStatusCode();
		if (statusCode == HttpStatus.SC_OK) {
            System.out.println("初始化12306成功.");
//            _12306Util.printCookies();
        }else {
            System.out.println("初始化12306失败，url="+_12306Util.initUrl+",statusCode="+statusCode);
            return;
        }
	}
	
	private static void initRail() throws ClientProtocolException, IOException {
		//获取RAIL_DEVICEID和RAIL_EXPIRATION
		HttpGet get = new HttpGet(_12306Util.railUrl);
		setGetRequestHeaders(get);
		CloseableHttpResponse response = _12306Util.getHttpClient().execute(get);
		int statusCode = response.getStatusLine().getStatusCode();
		if (statusCode == HttpStatus.SC_OK) {
            System.out.println("GetJS成功.");
            String resStr = EntityUtils.toString(response.getEntity());
            String str = resStr.substring(resStr.indexOf("{"),resStr.indexOf("}")+1);
//            System.out.println(str);
            JSONObject obj = JSON.parseObject(str);
            _12306Util.addRailCookies(obj.getString("exp"), obj.getString("dfp"));
            obj.clear();
            _12306Util.printCookies();
        }else {
            System.out.println("GetJS失败，url="+_12306Util.railUrl+",statusCode="+statusCode);
            return;
        }
	}
	
	/**
	 * 查询车次
	 * @param orderDate
	 * @param fromCode
	 * @param toCode
	 * @throws URISyntaxException
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	private static void sendQuery(String orderDate,String fromCode,String toCode,Map<String, Object> stopLines) throws URISyntaxException, ClientProtocolException, IOException {
		URI uri = new URIBuilder()
				.setScheme("https")
				.setHost("kyfw.12306.cn")
				.setPath("/otn/leftTicket/query")
				.setParameter("leftTicketDTO.train_date", orderDate) //2018-05-04
				.setParameter("leftTicketDTO.from_station", fromCode)
				.setParameter("leftTicketDTO.to_station", toCode)
				.setParameter("purpose_codes", "ADULT")
				.build();
		HttpGet get = new HttpGet(uri);
		CloseableHttpResponse response = _12306Util.getHttpClient().execute(get);
		int statusCode = response.getStatusLine().getStatusCode();
		String result = "";
		if (statusCode == HttpStatus.SC_OK) {
            System.out.println("查票成功.");
            result = EntityUtils.toString(response.getEntity());
        }else {
            System.out.println("查票失败，url="+uri+",statusCode="+statusCode);
            return;
        }
		JSONObject obj = JSON.parseObject(result);
		JSONArray trains = obj.getJSONObject("data").getJSONArray("result");
		for (Object object : trains) {
			String[] contents = object.toString().split("\\|");
			String lineCode =contents[3];
			String startStation =STATIONMAPPING.get(contents[6]);
			String endStation =STATIONMAPPING.get(contents[7]);
			String startTime =contents[8];
			String endTime =contents[9];
			String costTime =contents[10];
			String isOrder=contents[11];
			String travelIime=contents[13];
			String erdeng=contents[30];
			String yideng=contents[31];
			String tedeng=contents[32];
			if(lineCode.startsWith("G")) {
				System.out.println("|&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&|");
				List<StopLine> shutDownList=(List<StopLine>) stopLines.get("stopList");
				List<StopLine> collect =shutDownList.stream().filter(stopLine->lineCode.equals(stopLine.getLeft())).collect(Collectors.toList());
				String isStop=collect.size()>0?"是":"否";
				String stopInfo ="";
				if(collect.size()>0) {
					stopInfo ="-->"+stopLines.get("stopDate")+"备注："+collect.get(0).getTip();
				}
				System.out.println("|出发日期："+travelIime+"=>高铁列车："+lineCode+"["+startStation+"~"+endStation+"]["+startTime+"~"+endTime+"],耗时："+costTime+
						",【商务座特等座："+tedeng+",一等座："+yideng+",二等座二等包座："+erdeng+"】-->是否可预订："+isOrder+"; "+
						"是否停运："+isStop+stopInfo+"");
				System.out.println("|&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&|");
				System.out.println();
				System.out.println();
			}
		}
		
	}
	
	private static void queryTickets(String orderDate,String fromCode,String toCode,Map<String, Object> stopLines) throws ClientProtocolException, IOException, URISyntaxException {
		initLogin();
		initRail();
		sendQuery(orderDate, fromCode, toCode, stopLines);
	}
	
	private static Map<String,Object> findStopLines() throws Exception{
		 String shutdownUrl=_12306Util.shutdownUrlPrifix+"/shutdownNotice.html";
		 String dataUlr="";
		 Document doc = Jsoup.connect(shutdownUrl).timeout(1000).get();
		 Elements scripts=doc.getElementsByTag("script");
		 for (Element element : scripts) {
			String scriptContent= element.data();
			if(StringUtils.isBlank(scriptContent)&&element.attr("src").indexOf("js/shutdownNotice")!=-1) {
				dataUlr=_12306Util.shutdownUrlPrifix+"/"+element.attr("src");
				break;
			}
		 }
		//^[a-z0-9]{0,7}$--072b469,24f686e
		String stopTrainResult= HttpUtil.send("GET", dataUlr, null);
		JSONObject shutDownInfo=JSONObject.parseObject((stopTrainResult.split("i.listData=")[1]).split("},761")[0]) ;
		String topTitle=shutDownInfo.getString("topTitle");
		List<StopLine> stopTrains=JSONArray.parseArray(shutDownInfo.getString("list"),StopLine.class) ;
		Map<String,Object> resultMap=new HashMap<String, Object>();
		resultMap.put("stopDate", topTitle);
		resultMap.put("stopList", stopTrains);
		return resultMap;
	}
	
	/**
	 * 获取指定日期回北京的车票
	 * @param orderDate--订票日期
	 */
	private static void getTicketsToBeijing(String orderDate,String fromCode,String toCode ) {
		try {
			queryTickets(orderDate, fromCode, toCode,findStopLines());
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

	/**
	 * @param args
	 * @throws Exception 
	 */
	public static void main(String[] args) {
		//查询指定日期所有武汉到北京高铁的数据
		getTicketsToBeijing("2021-07-28","WHN","BJP");
	}

}
